package com.parking.certified.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.ObjectUtil;
import com.parking.certified.client.form.CertifiedSelectStallNumForm;
import com.parking.certified.client.inter.StallClient;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.parking.certified.dao.CertifiedAccountMapper;
import com.parking.certified.dto.*;
import com.parking.certified.entity.CertifiedAccount;
import com.parking.certified.entity.CertifiedInfo;
import com.parking.certified.dao.CertifiedInfoMapper;
import com.parking.certified.exception.CertifiedException;
import com.parking.certified.exception.CertifiedExceptionCode;
import com.parking.certified.form.*;
import com.parking.certified.service.CertifiedInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parking.certified.service.config.MapUtil;
import com.parking.common.core.model.PageInfo;
import com.parking.common.core.model.Result;
import com.parking.common.core.model.StateData;
import com.parking.common.web.util.OssUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 彭于晏
 * @since 2023年11月29日
 */
@Service
public class CertifiedInfoServiceImpl extends ServiceImpl<CertifiedInfoMapper, CertifiedInfo> implements CertifiedInfoService {
    @Resource
    private CertifiedInfoMapper certifiedInfoMapper;
    @Resource
    private CertifiedAccountMapper certifiedAccountMapper;
    @Resource
    private CertifiedInfoService certifiedInfoService;
    @Resource
    private OssUtil ossUtil;
    @Resource
    private StallClient stallClient;

    /***
     * 修改物业信息
     * @param form
     */
    @Override
    public void updateCertified(UpdateCertifiedForm form,Integer certifiedAccountId) {
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("certified_account_id",certifiedAccountId);
        CertifiedInfo info = certifiedInfoMapper.selectOne(wrapper);
        if (info==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        info.setCertifiedInfoTel(form.getCertifiedInfoTel());
        certifiedInfoMapper.updateById(info);
    }

    /***
     * 物业查询自己信息
     * @param certifiedAccountId
     * @return
     * @throws Exception
     */
    @Override
    public CertifiedInfoDTO selectCertifiedInfoAccount(Integer certifiedAccountId) throws Exception{
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("certified_account_id",certifiedAccountId);
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectOne(wrapper);
        if (certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        CertifiedSelectStallNumForm form = new CertifiedSelectStallNumForm();
        form.setCertifiedInfoId(certifiedInfo.getCertifiedInfoId());
        form.setStallType(0);
        Result<Integer> result = stallClient.certifiedSelectStallNum(form);
        if (result.getCode()==500){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_ERROR);
        }
        if (result.getCode()!=200){
            throw new CertifiedException(result.getMessage(),result.getCode());
        }
        Integer data = result.getData();
        form.setStallType(1);
        Result<Integer> result1 = stallClient.certifiedSelectStallNum(form);
        if (result1.getCode()==500){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_ERROR);
        }
        if (result1.getCode()!=200){
            throw new CertifiedException(result1.getMessage(),result1.getCode());
        }
        Integer data1 = result1.getData();
        CertifiedInfoDTO dto = BeanUtil.toBean(certifiedInfo, CertifiedInfoDTO.class);
        dto.setStallCommonNum(data);
        dto.setStallChargeNum(data1);
        return dto;
    }

    /***
     *平台查询物业
     * @param form
     * @return
     */
    @Override
    public PageInfo selectCertified(SelectCertifiedForm form,Integer platformId) {
        Page<CertifiedInfo> page = new Page<>(form.getPageNum()!=null?form.getPageNum():1, form.getPageSize()!=null?form.getPageSize():6);
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        if (form.getCertifiedInfoId()!=null){
            wrapper.eq("certified_info_id",form.getCertifiedInfoId());
        }
        if (form.getCertifiedInfoName()!=null){
            wrapper.like("certified_info_name",form.getCertifiedInfoName());
        }
        if (form.getCertifiedInfoTel()!=null){
            wrapper.like("certified_info_tel",form.getCertifiedInfoTel());
        }
        if(ObjectUtil.isNotEmpty(form.getCertifiedAccountState())&&form.getCertifiedAccountState()!=1){
            QueryWrapper<CertifiedAccount> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("user_state",form.getCertifiedAccountState());
            List<CertifiedAccount> list = certifiedAccountMapper.selectList(wrapper2);
            for (CertifiedAccount account : list) {
                wrapper.eq("certified_account_id",account.getCertifiedAccountId());
            }
        }
         certifiedInfoMapper.selectPage(page, wrapper);
        List<SelectCertifiedDTO> dtos = BeanUtil.copyToList(page.getRecords(), SelectCertifiedDTO.class);
        for (SelectCertifiedDTO dto : dtos) {
            CertifiedAccount certifiedAccount = certifiedAccountMapper.selectById(dto.getCertifiedAccountId());
            dto.setCertifiedAccountAccount(certifiedAccount.getCertifiedAccountAccount());
            dto.setCertifiedAccountState(certifiedAccount.getCertifiedAccountState());
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(dtos);
        return pageInfo;
    }

    /****
     *用户查询物业
     * @param form
     * @return
     */
    @Override
    public CertifiedInfoDTO selectUser(SelectCertifiedForm form,Integer userId) {
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        if (form.getCertifiedInfoName()!=null){
            wrapper.like("certified_info_name",form.getCertifiedInfoName());
        }
        if (form.getCertifiedInfoTel()!=null){
            wrapper.like("certified_info_tel",form.getCertifiedInfoTel());
        }
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectOne(wrapper);
        if (certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        CertifiedInfoDTO dto = BeanUtil.toBean(certifiedInfo, CertifiedInfoDTO.class);
        dto.setCertifiedInfoAddPerson(null);
        dto.setCertifiedInfoAddTime(null);
        return dto;
    }

    /***
     *  查询物业信息
     * @param certifiedAccountId
     * @return
     */
    @Override
    public SelectCertifiedInfoDTO selectCertifiedInfo(Integer certifiedAccountId) {
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("certified_account_id",certifiedAccountId);
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectOne(wrapper);
        if(certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NULL);
        }
        SelectCertifiedInfoDTO dto = BeanUtil.toBean(certifiedInfo, SelectCertifiedInfoDTO.class);

        return dto;
    }

    /***
     *根据物业信息ID查询物业
     * @param certifiedInfoId
     * @return
     */
    @Override
    public CertifiedInfoClientDto selectCertifiedInfoById(Integer certifiedInfoId) {
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("certified_info_id",certifiedInfoId);
        CertifiedInfo info = certifiedInfoMapper.selectOne(wrapper);
        if (info==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NULL);
        }
        CertifiedInfoClientDto dto = BeanUtil.toBean(info, CertifiedInfoClientDto.class);
        return dto;
    }

    /***
     * 更新物业评分
     * @param form
     */
    @Override
    public void certifiedScoring(CertifiedScoreForm form) {
        List<CertifiedScoreDto> scores = form.getCertifiedScores();
        HashMap<Integer, BigDecimal> map = new HashMap<>();
        for (CertifiedScoreDto score : scores) {
            map.put(score.getCertifiedInfoId(),score.getCertifiedInfoScore());
        }
        List<CertifiedInfo> infos = certifiedInfoMapper.selectList(new QueryWrapper<CertifiedInfo>()
                .in("certified_info_id", scores.stream()
                        .map(CertifiedScoreDto::getCertifiedInfoId).collect(Collectors.toList())));
        for (CertifiedInfo info : infos) {
           info.setCertifiedInfoScore(map.get(info.getCertifiedInfoId()));
        }
        certifiedInfoService.saveOrUpdateBatch(infos);
    }

    /***
     *根据经纬度查询物业
     * @param form 经纬度 距离
     * @return
     */
    @Override
    public Set<DistanceCertifiedInfoDto> distanceCertifiedCall(SelectDistanceCertifiedInfoForm form) {
        // 1. 从SelectDistanceCertifiedInfoForm对象中获取经纬度参数
        Double longitude = form.getCertifiedInfoLongitude();
        Double latitude = form.getCertifiedInfoLatitude();
        Long distance = form.getDistanceRange();
        if (longitude==null||latitude==null||distance==null) {
            throw new CertifiedException("参数不存在",1101);//参数不存在
        }
        List<CertifiedInfo> list = list();
        Set<DistanceCertifiedInfoDto> distanceCertifiedInfoDtos = new HashSet<>();
        if (list!=null||list.size()!=0) {
            for (CertifiedInfo certifiedInfo : list) {
                Double longitudeDB = certifiedInfo.getCertifiedInfoLongitude();
                Double latitudeDB = certifiedInfo.getCertifiedInfoLatitude();
                Double aDouble = MapUtil.calculateDistance(latitudeDB, longitudeDB, latitude, longitude);
                System.out.println("距离数："+aDouble);
                System.out.println("参数："+distance);
                if (aDouble<=(double) distance*6371) {
                    DistanceCertifiedInfoDto dto = BeanUtil.toBean(certifiedInfo, DistanceCertifiedInfoDto.class);
                    distanceCertifiedInfoDtos.add(dto);
                }
            }
        }
        return distanceCertifiedInfoDtos;
    }

    /***
     * 根据车位类型查询物业信息
     * @param form
     * @return
     * @throws Exception
     */
    @Override
    public CertifiedInfoDTO distanceCertifiedStall(CertifiedSelectStallNumForm form) throws Exception{
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("certified_info_id",form.getCertifiedInfoId());
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectOne(wrapper);
        if (certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        Result<Integer> result = stallClient.certifiedSelectStallNum(form);
        if (result.getCode()==500){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_ERROR);
        }
        if (result.getCode()!=200){
            throw new CertifiedException(result.getMessage(),result.getCode());
        }
        Integer data = result.getData();
        CertifiedInfoDTO dto = BeanUtil.toBean(certifiedInfo, CertifiedInfoDTO.class);
        dto.setStallChargeNum(data);
        dto.setStallCommonNum(data);
        if (data > 0) {
            dto.setStallChargeNum(0); // 0代表有充电桩
        } else {
            dto.setStallChargeNum(1); // 1代表没有充电桩
        }
        return dto;
    }

    /***
     * 上传物业营业执照
     * @param path
     * @param certifiedAccountId
     */
    @Override
    public void upLoad(String path, Integer certifiedAccountId) {
        CertifiedAccount account = certifiedAccountMapper.selectById(certifiedAccountId);
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_account_id",account.getCertifiedAccountId());
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectOne(wrapper);
        if (certifiedInfo==null) {
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        if (account.getCertifiedAccountState()!=StateData.CERTIFIED_STATE_ENABLE){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_ENABLE);
        }
        certifiedInfo.setCertifiedInfoImg(path);
        certifiedInfoMapper.insert(certifiedInfo);
    }

    /***
     * 修改物业营业执照
     * @param form
     * @throws IOException
     */
    @Override
    public void upCertifiedInfoImg(UpdateCertifiedImgForm form) throws IOException {
        CertifiedAccount account = certifiedAccountMapper.selectById(form.getCertifiedInfoId());
        if (account==null) {
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        if (account.getCertifiedAccountState()!= StateData.CERTIFIED_STATE_ENABLE) {
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_ENABLE);
        }
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectById(form.getCertifiedInfoId());
        //上传返回的新地址
        String newPath = ossUtil.uploadFile(form.getImage().getInputStream(), form.getFileName());
        //获取旧的头像地址
        String path = FileNameUtil.getName(certifiedInfo.getCertifiedInfoImg());
        //删除旧地址
        ossUtil.deleteFile(path);
        //修改头像
        certifiedInfo.setCertifiedInfoImg(newPath);
        certifiedInfoMapper.updateById(certifiedInfo);
    }

    /***
     * 用户查询物业信息
     * @param form
     * @return
     */
    @Override
    public List<CertifiedInfoDTO> selectCertifiedInfoForUser(SelectCertifiedInfoForUserForm form) {
        // 1. 从SelectDistanceCertifiedInfoForm对象中获取经纬度参数
        Double longitude = form.getCertifiedInfoLongitude();
        Double latitude = form.getCertifiedInfoLatitude();
        Long distance = form.getDistanceRange();

        if (longitude==null||longitude==0||latitude==null||latitude==0||distance==null||distance==0) {
            throw new CertifiedException("参数不存在",1101);//参数不存在
        }

        List<CertifiedInfo> list = list();
        List<CertifiedInfoDTO> certifiedInfoDTOS = new ArrayList<>();
        if (list!=null||list.size()!=0) {
            for (CertifiedInfo certifiedInfo : list) {
                Double longitudeDB = certifiedInfo.getCertifiedInfoLongitude();
                Double latitudeDB = certifiedInfo.getCertifiedInfoLatitude();
                Double aDouble = MapUtil.calculateDistance(latitudeDB, longitudeDB, latitude, longitude);
                if (aDouble<=(double) distance * 6371) {
                    CertifiedInfoDTO dto = BeanUtil.toBean(certifiedInfo, CertifiedInfoDTO.class);
                    certifiedInfoDTOS.add(dto);
                }
            }
        }
        return certifiedInfoDTOS;
    }

    /***
     * 修改车位价格
     * @param form
     * @param certifiedAccountId
     */
    @Override
    public void updateStallPrice(UpdateStallPriceForm form,Integer certifiedAccountId) {
        QueryWrapper<CertifiedInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("certified_account_id",certifiedAccountId);
        CertifiedInfo certifiedInfo = certifiedInfoMapper.selectOne(wrapper);
        if (certifiedInfo==null){
            throw new CertifiedException(CertifiedExceptionCode.CERTIFIED_IS_NOT_CERTIFIED);
        }
        certifiedInfo.setStallUnitPrice(form.getStallUnitPrice());
        certifiedInfo.setChargeUnitPrice(form.getChargeUnitPrice());
        certifiedInfoMapper.updateById(certifiedInfo);
    }
}
